"""
GLM天气查询助手

该模块实现了一个基于GLM大模型的天气查询系统，主要功能包括：
1. 通过GLM API实现中英文城市名称翻译
2. 调用WeatherAPI获取实时天气数据
3. 提供对话式交互界面

依赖库：
- zhipuai: GLM API客户端
- requests: HTTP请求库
- json: JSON数据处理
- os: 环境变量读取
"""
from zhipuai import ZhipuAI
import os
import requests
import json

# 初始化GLM客户端
client = ZhipuAI(api_key=os.getenv("GLM_API_KEY"))

# 定义天气API的调用函数
def getcurrentweather(location):
    """
    获取指定城市的当前天气信息
    
    参数:
        location (str): 城市名称(中英文皆可)
    
    返回:
        dict: 包含天气信息的字典，格式为WeatherAPI返回的原始JSON
    
    异常:
        可能抛出requests.exceptions.RequestException
    """
    # 判断是否为英文，如果不是则调用大模型翻译
    if not location.isascii():
        response = client.chat.completions.create(
            model="glm-4-0520",
            messages=[
                {"role": "system", "content": "你是一个翻译助手，将中文地名翻译成英文。"},
                {"role": "user", "content": f"请将以下中文城市名称翻译成英文，只需返回英文名称，不要解释或其他内容：{location}"}
            ],
            temperature=0,
        )
        location = response.choices[0].message.content.strip()
    
    # WeatherAPI配置参数
    APIkey = 'd94892357e6b825afa1c15556492f40e'  # WeatherAPI密钥
    language = 'zh-cn'  # 返回语言设置为中文
    url = 'https://api.weatherapi.com/v1/current.json'  # WeatherAPI端点
    
    # 构造请求参数
    params = {
        'key': APIkey,
        'q': location,  # 查询地点
        'lang': language  # 返回语言
    }
    print(f"正在查询天气参数: {params}")  # 调试日志
    
    # 发送HTTP GET请求并返回JSON响应
    response = requests.get(url, params=params)
    return response.json()

# 定义获取城市英文名称的函数
def getcitynameinenglish(city):
    """
    从本地JSON文件获取城市的英文名称
    
    参数:
        city (str): 中文城市名称
    
    返回:
        str: 对应的英文城市名称，若未找到则返回None
    
    异常:
        FileNotFoundError: 当chinacities.json文件不存在时
        json.JSONDecodeError: 当JSON文件格式错误时
    """
    try:
        with open('chinacities.json', 'r', encoding='utf-8') as file:
            cities_data = json.load(file)
            for item in cities_data:
                if item['city'] == city:
                    return item['en_name']
    except FileNotFoundError:
        print("File not found.")
    except json.JSONDecodeError:
        print("Error decoding JSON.")
    return None

# 定义对话状态
class DialogState:
    """
    对话状态管理类
    
    属性:
        messages (list): 存储对话消息的列表，每个消息为字典格式
    """
    def __init__(self):
        """初始化空消息列表"""
        self.messages = []

    def add_message(self, role, content):
        """
        添加消息到对话历史
        
        参数:
            role (str): 消息角色('user'或'assistant')
            content (str): 消息内容
        """
        self.messages.append({"role": role, "content": content})

    def reset(self):
        """重置对话状态，清空消息列表"""
        self.messages = []

# 初始化对话状态
dialog_state = DialogState()

# 定义工具列表
tools = [
    {
        "type": "function",
        "function": {
            "name": "getcurrentweather",
            "description": "获取指定城市的当前天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市名称"
                    }
                },
                "required": ["location"]
            }
        }
    }
]

# 主对话函数
def main():
    """
    主对话循环
    
    功能:
        1. 接收用户输入
        2. 调用GLM模型处理
        3. 执行天气查询功能调用
        4. 输出助手回复
    """
    while True:
        # 获取用户输入
        user_input = input("User: ")
        dialog_state.add_message("user", user_input)

        # 检查退出条件
        if user_input.lower() in ["exit", "quit", "bye"]:
            print("Assistant: Goodbye!")
            break

        # 调用GLM模型处理用户输入
        response = client.chat.completions.create(
            model="glm-4",  # 使用GLM-4模型
            messages=dialog_state.messages,  # 传入对话历史
            tools=tools,  # 可用的工具列表
            tool_choice="auto"  # 自动决定是否调用工具
        )

        if response.choices[0].message.tool_calls:
            tool_call = response.choices[0].message.tool_calls[0]
            if tool_call.function.name == "getcurrentweather":
                location = json.loads(tool_call.function.arguments)["location"]
                weather_info = getcurrentweather(location)
                dialog_state.add_message("assistant", json.dumps(weather_info, ensure_ascii=False))
            else:
                dialog_state.add_message("assistant", "不支持的函数调用")
        else:
            dialog_state.add_message("assistant", response.choices[0].message.content)

        print(f"Assistant: {dialog_state.messages[-1]['content']}")

if __name__ == "__main__":
    main()
